/*
 * 
 *  This file is part of Sourceprojects.org Lycia Copyright 2010 noctarius
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 */
package org.sourceprojects.lycia;

import org.sourceprojects.lycia.exceptions.LyciaInitializationException;

/**
 * Defines a factory API that enables applications to obtain instances of
 * {@link org.sourceprojects.lycia.ResourceResolver} either by given standard
 * implmentation or by configuring own implementation.
 * 
 * @author noctarius
 * @since 0.0.1
 */
public final class ResourceResolverFactory {

	/**
	 * Classname for the standard
	 * {@link org.sourceprojects.lycia.ResourceResolver} class to be created if
	 * no special implementation is given
	 */
	public static final String STANDARD_RESOURCERESOLVER_CLASS = "org.sourceprojects.lycia.internal.dom.ResourceResolverImpl";

	/**
	 * Obtain a new instance of a
	 * {@link org.sourceprojects.lycia.ResourceResolver}<br>
	 * Implementation used for {@link org.sourceprojects.lycia.ResourceResolver}
	 * is the standard one. The classloader to load up this implementation is
	 * the actual ContextClassLoader of the actual thread.
	 * 
	 * @return New instance of standard ResourceResolver implementation
	 * @throws LyciaInitializationException
	 *             If some exception occurs on initialization of the new
	 *             instance the exception is wrapped into a
	 *             {@link LyciaInitializationException}
	 */
	public static final ResourceResolver newInstance() {
		final ClassLoader classLoader = Thread.currentThread()
				.getContextClassLoader();
		return newInstance(STANDARD_RESOURCERESOLVER_CLASS, classLoader);
	}

	/**
	 * Obtain a new instance of a
	 * {@link org.sourceprojects.lycia.ResourceResolver}<br>
	 * Implementation used for {@link org.sourceprojects.lycia.ResourceResolver}
	 * is the standard one. The classloader to load up those implementations is
	 * the given classloader.
	 * 
	 * @param classLoader
	 *            The classloader to load classes
	 * @return New instance of standard ResourceResolver implementation
	 * @throws LyciaInitializationException
	 *             If some exception occurs on initialization of the new
	 *             instance the exception is wrapped into a
	 *             {@link LyciaInitializationException}
	 */
	public static final ResourceResolver newInstance(
			final ClassLoader classLoader) {
		return newInstance(STANDARD_RESOURCERESOLVER_CLASS, classLoader);
	}

	/**
	 * Obtain a new instance of a
	 * {@link org.sourceprojects.lycia.ResourceResolver}<br>
	 * Implementation used for {@link org.sourceprojects.lycia.ResourceResolver}
	 * must be given as parameter. The classloader to load up those
	 * implementations is the given classloader.
	 * 
	 * @param resolverImplementationClassname
	 *            Classname of the class implements ResourceResolver interface
	 *            and should be used isntead of standard implementation
	 * @param classLoader
	 *            The classloader to load classes
	 * @return New instance of standard ResourceResolver implementation
	 * @throws LyciaInitializationException
	 *             If some exception occurs on initialization of the new
	 *             instance the exception is wrapped into a
	 *             {@link LyciaInitializationException}
	 */
	@SuppressWarnings("unchecked")
	public static final ResourceResolver newInstance(
			final String resolverImplementationClassname,
			final ClassLoader classLoader) {
		Class<? extends ResourceResolver> resolverClass;
		try {
			resolverClass = (Class<? extends ResourceResolver>) classLoader
					.loadClass(resolverImplementationClassname);

			return resolverClass.newInstance();
		} catch (final Exception e) {
			throw new LyciaInitializationException(
					"Parser initialization failed", e);
		}
	}

	private ResourceResolverFactory() {
	}

}
